home *** CD-ROM | disk | FTP | other *** search
/ The CICA Windows Explosion! / The CICA Windows Explosion! - Disc 2.iso / programr / wtj008.zip / ORG.ZIP / ORGWIN.PAS < prev    next >
Pascal/Delphi Source File  |  1992-06-30  |  24KB  |  802 lines

  1. {**************************************************}
  2. {                     OrgWindow                    }
  3. {                    Written in                    }
  4. {             Turbo Pascal for Windows             }
  5. {                       by                         }
  6. {                  Zack Urlocker                   }
  7. {**************************************************}
  8. Unit OrgWin;
  9.  
  10. interface
  11.  
  12. uses OGL1, OGL2, OGL3, RGBDialog,   { ObjectGraphics }
  13.      WObjects, StdDlgs, Strings, WinTypes, WinProcs;
  14.  
  15. const
  16.  cm_Cut    = 201;      { constants for main window menus} 
  17.  cm_Copy   = 202;
  18.  cm_Paste  = 203;
  19.  cm_Clear  = 204;
  20.  cm_Select = 109; 
  21.  cm_Line   = 110;
  22.  cm_DotLine= 111;
  23.  cm_EmpRect = 112;
  24.  cm_Rect   = 113;
  25.  cm_RndRect= 114;
  26.  cm_Text   = 115;
  27.  cm_Data   = 309;
  28.  FieldLen  =  24;      { Dialog constants }
  29.  id_Name   = 104;
  30.  id_Posn   = 106;
  31.  id_Dept   = 108;
  32.  
  33. Type
  34.  
  35.   { Transfer record for Dialog }
  36.   ItemTransferBuffer = record
  37.     NameStr, PosnStr, DeptStr : array[0..FieldLen-1] of char;
  38.   end;
  39.  
  40.   { Keep an array of all the items, indexed by graphic ID }
  41.   ItemsArray = array[0..50] of ItemTransferBuffer;
  42.  
  43.   { The dialog is used for input of new employee info }
  44.   PDataDialog = ^TDataDialog;
  45.   TDataDialog = object(TDialog)
  46.     NameEdit, PosnEdit, DeptEdit : PEdit;
  47.     constructor Init(AParent: PWindowsObject; ATitle:PChar);
  48.   end;
  49.  
  50.   { Custom input field; loses focus when Enter is pressed }
  51.   PRetEdit = ^TRetEdit;
  52.   TRetEdit = object(TEdit)
  53.     procedure wmChar(var Msg:TMessage); virtual wm_Char;
  54.   end;
  55.  
  56.   { Employee graphic object }
  57.   PEmpRect = ^TEmpRect;
  58.   TEmpRect = object(TRectangle)
  59.     function  Copy: Pointer; virtual;
  60.     procedure drawOn(APort:PPort); virtual;
  61.     constructor Load(var S: TStream);
  62.     procedure Store(var S: TStream); virtual;
  63.   end;
  64.  
  65.   { Drawing area window }
  66.   POrgWindow = ^TOrgWindow;
  67.   TOrgWindow = object(TGWindow)
  68.     LabelEC: PRetEdit;   { Edit control          }
  69.     Graphic: PGraphic;   { Graphic being drawn   }
  70.     Chosen: PSubPicture; { selected item         }
  71.     Marks: PPolymark;    { to mark selected item }
  72.     HitPt: PGPoint;      { mouse click location  }
  73.     Saved: Boolean;      { has work been saved?  }
  74.     ViewGrid : Boolean;  { is grid view on?      }
  75.     Tool: Integer;       { what tool is selected }
  76.     CurrPen: PPen;       { current tool settings }
  77.     CurrBrush: PBrush;
  78.     CurrTextPen: PTextPen;
  79.     ItemBuffer : ItemTransferBuffer; { for Dialog }
  80.     ItemsCount : Integer;
  81.     constructor Init(AParent: PWindowsObject; ATitle: PChar);
  82.     procedure SetupWindow; virtual;
  83.     destructor Done; virtual;
  84.     procedure GPaint(APort: PPort; BadRect: PMathRect);virtual;
  85.     {mouse messages}
  86.     procedure BeginDrag(MousePt: PGPoint; KeyStates: Word); virtual;
  87.     procedure Drag(MousePt: PGPoint; KeyStates: Word); virtual;
  88.     procedure EndDrag(MousePt: PGPoint; KeyStates: Word); virtual;
  89.     procedure WMLButtonDblClick(var Msg: TMessage); virtual WM_LBUTTONDBLCLK;
  90.     procedure WMSetFocus(var Msg: TMessage); virtual WM_SETFOCUS;
  91.     {Methods to interface with Main Window}
  92.     procedure ClearAll;
  93.     procedure SetTool(ToolID: Integer);virtual;
  94.     procedure SetColor(Color:PLogColor);virtual;
  95.     procedure SetWidth(Width:Integer);
  96.     procedure SetCurrTextPen(ATPen: PTextPen);virtual;
  97.     procedure Print(Printer: PGPrinter);virtual;
  98.     procedure CutChoice; virtual;
  99.     procedure CopyChoice; virtual;
  100.     procedure PasteChoice; virtual;
  101.     procedure ClearChoice; virtual;
  102.     procedure SetScrollState(ScrollState: Boolean);virtual;
  103.     procedure SetSpace(NewSpace: PGraphSpace);virtual;
  104.   end;
  105.  
  106. var
  107.     Items : ItemsArray;  { Global }
  108.  
  109. implementation
  110.  
  111. {--------------------------------------------------}
  112. { TRetEdit method implementations:                 }
  113. {--------------------------------------------------}
  114.  
  115. { if Enter is pressed send focus back; otherwise process input }
  116. procedure TRetEdit.wmChar(var Msg:TMessage);
  117. var key : word;
  118. begin
  119.   key := Msg.wParam;
  120.   if (key = word(#13)) or (key = word(#27))
  121.   then
  122.     { exit }
  123.     setFocus(Application^.mainWindow^.HWindow)
  124.   else
  125.     defWndProc(Msg);
  126. end;
  127.  
  128. { The edit controls will contain the transfer data. }
  129. constructor TDataDialog.Init(AParent: PWindowsObject; ATitle:PChar);
  130. begin
  131.   TDialog.Init(AParent, ATitle);
  132.   new(NameEdit, initResource(@Self, id_Name, fieldLen));
  133.   new(PosnEdit, initResource(@Self, id_Posn, fieldLen));
  134.   new(DeptEdit, initResource(@Self, id_Dept, fieldLen));
  135. end;
  136.  
  137. {--------------------------------------------------}
  138. { TEmpRect method implementations:                 }
  139. {--------------------------------------------------}
  140.  
  141. { Create a copy of the new EmpRect }
  142. function TEmpRect.Copy:Pointer;
  143. var
  144.   NewRect: PEmpRect;
  145. begin
  146.   New(NewRect, InitDefault);
  147.   NewRect^.CopyFrom(@Self);
  148.   Copy := NewRect;
  149. end;
  150.  
  151. { Draw 2 rectangles for 3D effect }
  152. procedure TEmpRect.drawOn(APort:PPort);
  153. var TEmpRect : PRectangle;
  154.     OffPt : TGPoint;
  155.     col: TColor;
  156. begin
  157.   { draw the first one with a brush }  
  158.   New(TEmpRect, initDefault);
  159.   TEmpRect^.CopyFrom(@Self);
  160.   TEmpRect^.inflate(-4, -4);
  161.   TEmpRect^.brush^.Pattern := bp_thirty;
  162.   TEmpRect^.brush^.setColor(TEmpRect^.Pen^.color{@col});
  163.   TEmpRect^.Draw(APort);
  164.   { draw the second one moved over, white }
  165.   OffPt.init(-4,-4);
  166.   TEmpRect^.offset(@OffPt);
  167.   TEmpRect^.brush^.Pattern := bp_solid;
  168.   col.init(ps_white); 
  169.   TEmpRect^.brush^.setColor(@col);
  170.   TEmpRect^.Draw(APort);
  171.   OffPt.Done;
  172. end;
  173.  
  174. { Load additional information for employee }
  175. constructor TEmpRect.Load(var S: TStream);
  176. var S1 : PChar;
  177. begin
  178.   TRectangle.Load(S);
  179.   S1 := S.StrRead;
  180.   StrCopy(Items[ID].NameStr, S1);
  181.   S1 := S.StrRead;
  182.   StrCopy(Items[ID].PosnStr, S1);
  183.   S1 := S.StrRead;
  184.   StrCopy(Items[ID].DeptStr, S1);
  185. end;
  186.  
  187. { Store additional information for employee}
  188. procedure TEmpRect.Store(var S: TStream);
  189. begin
  190.   TRectangle.Store(S);
  191.   S.StrWrite(Items[ID].NameStr);
  192.   S.StrWrite(Items[ID].PosnStr);
  193.   S.StrWrite(Items[ID].DeptStr);
  194. end;
  195.  
  196. {--------------------------------------------------}
  197. { TOrgWindow method implementations:               }
  198. {--------------------------------------------------}
  199.  
  200. { Initialize fields, setup style, scrollers etc  }
  201. constructor TOrgWindow.Init(AParent: PWindowsObject;ATitle: PChar);
  202. var GridSize:TGPoint;
  203. begin
  204.   TGWindow.Init(AParent, ATitle);
  205.   Attr.Style := Attr.Style or ws_Child   or ws_Border 
  206.                            or ws_VScroll or ws_HScroll; 
  207.  
  208.   { Create scroller object specifiying size, range }                            
  209.   Scroller := New(PGScroller, Init(@Self, 20, 20,
  210.                   Space^.WorldRect^.Width,
  211.                   Space^.WorldRect^.Height));
  212.   Scroller^.XLine   := Space^.Granularity;
  213.   Scroller^.YLine   := Space^.Granularity;
  214.   Scroller^.AutoMode:= False;
  215.  
  216.   Marks := New(PPolymark, InitDefault);
  217.   New(Chosen, InitDefault);
  218.  
  219.   { Always start with a grid }
  220.   GridSize.init(20,20);
  221.   Space^.setGrid(@GridSize);
  222.   GridSize.done;
  223.   ViewGrid := True;
  224.   Saved := True;
  225.   Tool := cm_EmpRect;
  226.   Graphic := New(PEmpRect, init(0,0,0,0, tc_Tools));
  227.   ItemsCount := 0;
  228.   LabelEC := nil;
  229.   New(CurrPen,     InitDefault);
  230.   New(CurrBrush,   InitDefault);
  231.   New(CurrTextPen, InitDefault);
  232. end;
  233.  
  234. { Clean up all objects }
  235. destructor TOrgWindow.Done;
  236. begin
  237.   Dispose(Graphic, Done);
  238.   Dispose(CurrPen, Done);
  239.   Dispose(CurrBrush, Done);
  240.   Dispose(CurrTextPen, Done);
  241.   TGWindow.Done;
  242. end;
  243.  
  244.  
  245. { This is the central method for handling mouse clicks and dragging }
  246. procedure TOrgWindow.BeginDrag(MousePt: PGPoint; KeyStates: Word);
  247. var  APt    : TGPoint;
  248.      AString: array [0..50] of Char;
  249.  
  250. { Respond to mouse click when Text tool is selected.
  251.   Note that you execute this code once when selecting text
  252.   and a second time when selecting elsewhere to finish }
  253.   procedure BeginTextDrag;
  254.   begin
  255.     if LabelEC = nil then
  256.     { Initial mouseclick to start text entry }
  257.     begin
  258.       { Create and display edit field for input }
  259.       Space^.WorldToDisplay(MousePt, APt);
  260.       LabelEC:= New(PRetEdit, Init(@Self, 555, '',
  261.                APt.X, APt.Y, 120, 24, 50, False));
  262.       Graphic^.SetOrigin(MousePt);
  263.       Graphic^.SetTextPen(CurrTextPen);       
  264.       Application^.MakeWindow(LabelEC);
  265.       SetFocus(LabelEC^.HWindow);
  266.     end
  267.     else
  268.     { Second mouseclick elsewhere to end text entry }
  269.     begin
  270.       { find out what text was entered, show it }
  271.       LabelEC^.GetText(@AString, 50);
  272.       Dispose(LabelEC, Done);
  273.       LabelEC := nil;
  274.       if StrLen(AString) > 0 then
  275.       begin
  276.         PLabel(Graphic)^.SetText(AString);
  277.         Graphic^.SetTextPen(CurrTextPen); 
  278.         Graphic^.Draw(Port);
  279.         Picture^.Add(Graphic^.Copy);
  280.       end;
  281.     end;
  282.   end;
  283.  
  284. { Respond to mouse click when select tool is selected. }
  285.   procedure BeginSelectDrag;
  286.   var
  287.     BRect: TMathRect;
  288.   begin
  289.     BRect.InitDefault;
  290.     Chosen^.GetBoundsRect(BRect);
  291.  
  292.     HitPt := MousePt^.Copy;  { Used for dragging selections }
  293.  
  294. { Non-Zero count means we've got something selected that
  295.   we will move; otherwise we're making a new selection }
  296.     if (Chosen^.Count > 0) and
  297.        (BRect.Contains(MousePt)) then
  298.     begin
  299.       { start moving the current selected item }
  300.       Dispose(Graphic, Done);        { Get rid of the Chooser }
  301.       Graphic := New(PRegion, Init(tc_Tools));
  302.       Chosen^.GetFastRegion(Graphic^);
  303.     end
  304.     else
  305.     begin
  306.       { select a new item }
  307.       if Marks^.Count > 0 then
  308.         Marks^.Draw(Port);   { Erase the old marks, if any...      }
  309.       Marks^.FreeAll;        { and clear so GPaint won't draw them }
  310.       Chosen^.FreeAll;       { Clear any existing selection        }
  311.       Dispose(Graphic, Done);
  312.       Graphic := New(PChooser, Init(MousePt^.X, MousePt^.Y));
  313.     end;
  314.     BRect.Done;
  315.   end;
  316.  
  317.  
  318. { BeginDrag }
  319. begin
  320.  { Always snap to grid unless selecting }
  321.   if (Tool <> cm_Select) or (Chosen^.Count > 0) then
  322.     Space^.snapToGrid(MousePt^);
  323.  
  324.   if Tool = cm_Text then
  325.     beginTextDrag
  326.   else
  327.   if Tool = cm_Select then 
  328.     beginSelectDrag
  329.   else
  330.     if Tool = cm_EmpRect then  { give unique ID for storing data }
  331.     begin
  332.        inc(ItemsCount);
  333.        Graphic^.ID := ItemsCount;
  334.     end;
  335.  
  336.   Graphic^.Pen^.Combo := cb_Nxor;
  337.   Graphic^.SetOrigin(MousePt);
  338.   Graphic^.SetCorner(MousePt);
  339.   Port^.Associate(@Self);
  340.   Graphic^.Draw(Port);
  341. end;
  342.  
  343. { When dragging something redraw it }
  344. procedure TOrgWindow.Drag(MousePt: PGPoint; KeyStates: Word);
  345. var
  346.   OffsetPt: TGPoint;
  347. begin
  348.  { Always snap to grid unless selecting }
  349.   if (Tool <> cm_Select) or (Chosen^.Count > 0) then
  350.     Space^.snapToGrid(MousePt^);
  351.  
  352.   if (Tool = cm_Select) and (Chosen^.Count > 0) then
  353.   begin
  354.   { start moving the selected item }
  355.     begin
  356.       HitPt^.OffsetFrom(MousePt, OffsetPt);
  357.       Graphic^.Offset(@OffsetPt);
  358.       HitPt^.CopyFrom(MousePt);
  359.     end;
  360.   end;
  361.  
  362.   { Redraw for dragging effect }
  363.   if Tool <> cm_Text then
  364.   begin
  365.     Graphic^.FastDraw(Port);
  366.     Graphic^.SetCorner(MousePt);
  367.     Graphic^.FastDraw(Port);
  368.   end;
  369. end;
  370.  
  371. { This is the main routine for whenever the user release the mouse. }  
  372. procedure TOrgWindow.EndDrag(MousePt: PGPoint; KeyStates: Word);
  373. var
  374.   APolyshape: PPolyshape;
  375.   BRect     : TRectangle;
  376.   OrigPt, APt : TGPoint;
  377.   AString: array [0..50] of Char;
  378.  
  379.   { End a drag action with the select tool }
  380.   procedure EndSelectDrag;
  381.   var
  382.     TempChosen    : PSubPicture;
  383.     XScale, YScale: Integer;
  384.     OffsetPt: TGPoint;
  385.   begin
  386. { Non-zero count means we're moving an existing selection;
  387.   otherwise we're making a new selection by putting it in Chosen }
  388.  
  389.     if Chosen^.Count > 0 then
  390.    { Relocate a moved selection.  First, clear away the marks,
  391.      then invalidate the Chosen in its old position, move it,
  392.      invalidate in its new position, and then re-mark it. }
  393.     begin
  394.       Marks^.Draw(Port);
  395.       Chosen^.Invalidate(Port);
  396.       Chosen^.PositionAt(Graphic^.Origin);
  397.       Picture^.FindBounds;     { In case Chosen moved outside them }
  398.       Marks^.FreeAll;
  399.       Chosen^.Invalidate(Port);
  400.       Chosen^.MarkCorners(Marks);
  401.       Marks^.Draw(Port);
  402.     end
  403.     else
  404.     { See what was selected.  Tell the Chooser (current Graphic) to
  405.       collect the chosen objects into Chosen, then mark the selection
  406.       and draw the marks. } 
  407.     begin
  408.       PChooser(Graphic)^.Choose(Picture, Chosen^);
  409.       Chosen^.MarkCorners(Marks);
  410.       Marks^.Draw(Port);
  411.    end;
  412.    { Chooser is still visible, so erase it when we're done}
  413.     Graphic^.Pen^.Combo := cb_NXOr;
  414.     Graphic^.Draw(Port);
  415.   end;
  416.  
  417. begin { EndDrag }
  418.   BRect.InitDefault;
  419.  
  420.   if Tool = cm_Select then
  421.     EndSelectDrag
  422.  
  423.   else 
  424.   if Tool <> cm_Text then
  425.   begin
  426.     Graphic^.Pen^.Combo := cb_Copy;
  427.     { Dotted lines are not affected by width }
  428.     if Tool = cm_DotLine then
  429.       Graphic^.Pen^.setColor(CurrPen^.Color)
  430.     else
  431.       Graphic^.SetPen(CurrPen);
  432.     Graphic^.Draw(Port);
  433.     Port^.Dissociate;
  434.     Picture^.Add(Graphic^.Copy);
  435.     BRect.Done;
  436.   end;
  437. end;
  438.  
  439. { Respond to Right click action by displaying dialog box}
  440. procedure TOrgWindow.WMLButtonDblClick(var Msg: TMessage);
  441. var
  442.   TempGraphic : PGraphic;
  443.   CurItem : Word;
  444.   EmpRect : PEmpRect;
  445.   Dlg: TDataDialog;
  446.   Reply : Word;
  447. begin
  448.    TempGraphic := Chosen^.first;
  449.    if TempGraphic <> nil then
  450.    if (typeOf(TempGraphic^) = typeof(TEmpRect)) then
  451.    begin
  452.      { Get information into buffer }
  453.      Dlg.Init(@Self, 'DataDlg');
  454.      CurItem := TempGraphic^.ID;
  455.      strCopy(ItemBuffer.NameStr, Items[CurItem].NameStr);
  456.      strCopy(ItemBuffer.PosnStr, Items[CurItem].PosnStr);
  457.      strCopy(ItemBuffer.DeptStr, Items[CurItem].DeptStr);
  458.      Dlg.TransferBuffer := @ItemBuffer;
  459.      Reply := Dlg.Execute;
  460.      Dlg.Done;
  461.      if Reply = id_Ok then
  462.      begin
  463.      { Get information out of buffer }
  464.       strCopy(Items[CurItem].NameStr, ItemBuffer.NameStr);
  465.       strCopy(Items[CurItem].PosnStr, ItemBuffer.PosnStr);
  466.       strCopy(Items[CurItem].DeptStr, ItemBuffer.DeptStr);
  467.      end;
  468.    end
  469.    else
  470.     MessageBeep(0);
  471. end;
  472.  
  473.  
  474. { Trap the WMSetFocus message so that when the user
  475.   hits return in the edit field we can get the input }
  476. procedure TOrgWindow.WMSetFocus(var Msg: TMessage);
  477. var AString:array[0..50] of char;
  478.  TempGraphic : PGraphic;
  479.  TempPt : TGPoint;
  480. begin
  481. if LabelEC <> nil then
  482.  begin
  483. { Restart here when you get the focus!}
  484.   LabelEC^.GetText(@AString, 50);
  485.   Dispose(LabelEC, Done);
  486.   LabelEC := nil;
  487.   if StrLen(AString) > 0 then
  488.   begin
  489.     TempGraphic := New(PLabel, Init(0,0, '', tc_Tools));
  490.     { Actually, should center it here }
  491.     TempGraphic^.SetOrigin(Graphic^.Origin);
  492.     TempGraphic^.SetTextPen(CurrTextPen);
  493.     PLabel(TempGraphic)^.SetText(AString);
  494.     Picture^.Add(TempGraphic^.Copy);
  495.     TempGraphic^.Draw(Port);
  496.     TempGraphic^.done;
  497.   end;
  498.  end;
  499. end;
  500.  
  501. { Take care of last minute initialization after window is created }
  502. procedure TOrgWindow.SetupWindow;
  503. begin
  504.   TGWindow.SetupWindow;
  505.   SetGCursor(cs_Graphic);
  506. end;
  507.  
  508. { Override default painting to show grid, marks, page border }
  509. procedure TOrgWindow.GPaint(APort: PPort; BadRect: PMathRect);
  510. var
  511.   PageBorder: TRectangle;
  512. begin
  513.  { Show the grid if view is turned on }
  514.   if ViewGrid then
  515.     APort^.DrawGrid;
  516.  
  517.   TGWindow.GPaint(APort, BadRect);
  518.   if Marks^.Count > 0 then
  519.     Marks^.Draw(APort);
  520.  
  521.   PageBorder.Init(Space^.WorldRect^.Origin^.X, Space^.WorldRect^.Origin^.Y,
  522.                   Space^.WorldRect^.Corner^.X, Space^.WorldRect^.Corner^.Y,
  523.                   tc_Tools);
  524.   PageBorder.Brush^.Pattern := bp_Invisible;
  525.   PageBorder.Draw(APort);
  526.   PageBorder.Done;
  527. end;
  528.  
  529. { Start a new drawing }
  530. procedure TOrgWindow.ClearAll;
  531. var i : integer;
  532. begin
  533.     Picture^.FreeAll;
  534.     Marks^.FreeAll;
  535.     Chosen^.FreeAll;
  536.     for i := 1 to 50 do
  537.     begin
  538.        StrPCopy(Items[i].NameStr, '');
  539.        StrPCopy(Items[i].PosnStr, '');
  540.        StrPCopy(Items[i].DeptStr, '');
  541.     end;
  542.     invalidate;
  543. end;
  544.  
  545. { Set the tool and create the appropriate graphic }
  546. procedure TOrgWindow.SetTool(ToolID: Integer);
  547. begin
  548.   Tool := ToolID; 
  549. { Check to see if the Text Edit control is active.  If it is, destroy
  550.   it whenever a tool is selected (even Text; we will just recreate it).}
  551.   if LabelEC <> nil then
  552.   begin
  553.     Dispose(LabelEC, Done);
  554.     LabelEC := nil;
  555.   end;
  556. { Clean up selection and dragging.  Whatever the current drawing object is,
  557.   draw it to clear it away, then delete it and reconstruct it based on what
  558.   was selected. }
  559.   Port^.Associate(@Self); 
  560.   Marks^.Draw(Port);      
  561.   Marks^.FreeAll;         
  562.   Chosen^.FreeAll;        
  563.   if Graphic <> nil then
  564.   begin
  565.     Dispose(Graphic, Done);
  566.     Graphic := nil;
  567.   end;
  568.   Port^.Dissociate;
  569.  
  570.   { Create the appropriate tool and set the cursor } 
  571.   case Tool of
  572.     cm_Select   : begin
  573.             Graphic := New(PChooser, InitDefault);
  574.                     Marks^.SetMark(nil);
  575.             SetGCursor(cs_Pointer);
  576.           end;
  577.     cm_Line     : begin
  578.             Graphic := New(PLine, Init(0,0, 0,0, tc_Tools));
  579.                     Graphic^.pen^.style := ls_Solid;
  580.             SetGCursor(cs_ThinCross);
  581.           end;
  582.     cm_DotLine  : begin
  583.             Graphic := New(PLine, Init(0,0, 0,0, tc_Tools));
  584.                     Graphic^.pen^.style := ls_Dot;
  585.                     Graphic^.pen^.width := 0; 
  586.                SetGCursor(cs_ThinCross);
  587.           end;
  588.     cm_EmpRect:    begin
  589.             Graphic := New(PEmpRect, Init(0,0, 0,0, tc_Tools));
  590.             SetGCursor(cs_ThinCross);
  591.           end;
  592.     cm_Rect:      begin
  593.             Graphic := New(PRectangle, Init(0,0, 0,0, tc_Tools));
  594.             SetGCursor(cs_ThinCross);
  595.           end;
  596.     cm_RndRect  : begin
  597.             Graphic := New(PRoundRect, Init(0,0, 0,0, tc_Tools));
  598.             SetGCursor(cs_ThinCross);
  599.           end;
  600.     cm_Text     : begin
  601.             Graphic := New(PLabel, Init(0,0, '', tc_Tools));
  602.             SetGCursor(cs_IBeam);
  603.           end;
  604.   end;
  605. end;
  606.  
  607. { Set the color of all tools }
  608. procedure TOrgWindow.SetColor(Color:PLogColor);
  609. begin
  610.   CurrPen^.setColor(Color);
  611.   Graphic^.Pen^.setColor(Color);
  612.   CurrTextPen^.setColor(Color);
  613. end;
  614.  
  615. { Set the width of Pen }
  616. procedure TOrgWindow.SetWidth(Width:Integer);
  617. begin
  618.   CurrPen^.Width := Width;
  619.   if tool <> cm_DotLine then
  620.     Graphic^.Pen^.Width := width;
  621. end;
  622.  
  623. procedure TOrgWindow.SetCurrTextPen(ATPen: PTextPen);
  624. begin
  625. end;
  626.  
  627.  
  628. { Update scrollers }
  629. procedure TOrgWindow.SetScrollState(ScrollState: Boolean);
  630. begin
  631.   if ScrollState then
  632.   begin
  633.     ShowScrollBar(HWindow, sb_Both, True);
  634.     PGScroller(Scroller)^.XPos := Space^.MappingRect^.Left;
  635.     PGScroller(Scroller)^.YPos := Space^.MappingRect^.Top;
  636.   end
  637.   else
  638.     ShowScrollBar(HWindow, sb_Both, False);
  639. end;
  640.  
  641.  
  642. {------------------------------------------------------------------
  643.  Redefine the ancestral SetSpace method, so that we may plug any
  644.  new GraphSpace units into our scrollers.  Calls on the ancestral
  645.  method to actually set the space.
  646.  ------------------------------------------------------------------
  647. }
  648. { Is this really necessary? }
  649. procedure TOrgWindow.SetSpace(NewSpace: PGraphSpace);
  650. begin
  651.   TGWindow.SetSpace(NewSpace);
  652.   Scroller^.XLine := Space^.Granularity;
  653.   Scroller^.YLine := Space^.Granularity;
  654.   Scroller^.SetRange(Space^.WorldRect^.Width, Space^.WorldRect^.Height);
  655. end;
  656.  
  657. { Print the picture }
  658. procedure TOrgWindow.Print(Printer: PGPrinter);
  659. var
  660.   PrintingOff: TGPoint;
  661.   PrintSpace : PGraphSpace;
  662. begin
  663. { Un-do any scrolling or zooming present in the window's
  664.   Space by resetting the MappingRect to be the world.
  665. }
  666.   PrintSpace := Space^.Copy;
  667.   PrintSpace^.SetMappingRect(PrintSpace^.WorldRect);
  668.   PrintSpace^.SetZoomLevel(100, 100);
  669.   Printer^.SetSpace(PrintSpace);
  670.   Dispose(PrintSpace, Done);
  671.  
  672.   Port^.AssociatePrinter(Printer);
  673.   Port^.SetSpace(Printer^.Space);
  674. {
  675.  Reposition the Mapping Rectangle of the Port to account for the
  676.  physical offset of the printer.  NOTE that these conversions are
  677.  not done until after association because they deal with Display
  678.  coordinates, and these do not accurately reflect the resolution
  679.  of the Printer until it is associated.
  680. }
  681.   Printer^.GetPhysicalOffset(PrintingOff);
  682.   Port^.Space^.DisplayToWorld(@PrintingOff, PrintingOff);
  683.   Port^.Space^.MoveMappingRect(@PrintingOff);
  684.  
  685.   Picture^.Draw(Port);
  686.   Port^.DissociatePrinter;
  687. end;
  688.  
  689. { Cut an item }
  690. procedure TOrgWindow.CutChoice;
  691. begin
  692.   CopyChoice;
  693.   ClearChoice;
  694. end;
  695.  
  696. {------------------------------------------------------------------
  697.  Copy TheChosen out of the Picture and post it to the Clipboard.
  698.  ------------------------------------------------------------------}
  699. procedure TOrgWindow.CopyChoice;
  700. begin
  701.   if Chosen^.Count > 0 then
  702.   begin
  703.     Port^.Associate(@Self);
  704.     Port^.ToClipboard(Chosen);
  705.     Port^.Dissociate;
  706.   end;
  707. end;
  708.  
  709. {------------------------------------------------------------------
  710.  Paste the contents of the Clipboard into the Picture.  Put the
  711.  new objects in the center of the Window, and automatically marks
  712.  them for subsequent positioning.
  713.  ------------------------------------------------------------------}
  714. procedure TOrgWindow.PasteChoice;
  715. var
  716.   CenterPt: TGPoint;
  717.   DRect   : TMathRect;
  718.   ASpace  : TGraphSpace;
  719.  
  720.   procedure AddIt(AGraphic: PGraphic); far;
  721.   begin
  722.     Picture^.Add(AGraphic);
  723.   end;
  724. begin
  725.   Port^.Associate(@Self);
  726.   Marks^.Draw(Port);      { Erase current Marks if any,  }
  727.   Marks^.FreeAll;         { then clear for later re-mark.}
  728.   Chosen^.FreeAll;
  729. {
  730.  By reading the contents of the Clipboard into a SubPicture
  731.  (TheChosen), we can then transfer the objects into the Picture
  732.  without copying them, since TheChosen does not assume ownership.
  733.  Also, note that we ignore the Space coming in from the clipboard,
  734.  choosing instead to impose the current space on the objects.  A
  735.  more complete application might use the incoming space to do some
  736.  sort of units conversion on the objects.
  737. }
  738.   ASpace.InitDefault;
  739.   Port^.FromClipboard(ASpace, Chosen^);
  740.   if Chosen^.Count > 0 then
  741.   begin
  742.     DRect.InitDefault;
  743.     GetDisplayRect(DRect);
  744.     CenterPt.Init(DRect.Width div 2, DRect.Height div 2);
  745.     Space^.DisplayToWorld(@CenterPt, CenterPt);
  746.     Chosen^.CenterAt(@CenterPt);
  747.     if Chosen^.Count > 0 then
  748.     begin
  749.       Chosen^.ForEach(@AddIt);
  750.       Chosen^.MarkCorners(Marks);
  751.       Chosen^.Draw(Port);
  752.       Marks^.Draw(Port);
  753.       PGWindow(Parent)^.SetPicture(Chosen);
  754.     end;
  755.     DRect.Done;
  756.   end;
  757.   Port^.Dissociate;
  758.   ASpace.Done;
  759. end;
  760.  
  761. {------------------------------------------------------------------
  762.  Clear TheChosen from the Picture, and from the screen.  Remove
  763.  TheMarks, since there's nothing left to mark.
  764.  ------------------------------------------------------------------}
  765. procedure TOrgWindow.ClearChoice;
  766. var
  767.   BRect: TRectangle;
  768.  
  769.   procedure RemoveIt(AGraphic: PGraphic); far;
  770.   begin
  771.     Picture^.Delete(AGraphic);
  772.   end;
  773. begin
  774.   if Chosen^.Count > 0 then
  775.   begin
  776.     BRect.InitDefault;
  777.     Marks^.GetBoundsRect(BRect);
  778.     Marks^.FreeAll;
  779.     Chosen^.ForEach(@RemoveIt);
  780.     Chosen^.FreeAll;
  781.     Port^.Associate(@Self);
  782.     BRect.Invalidate(Port);
  783.     Port^.Dissociate;
  784.     BRect.Done;
  785.  
  786.     PGWindow(Parent)^.SetPicture(Chosen);
  787.   end;
  788. end;
  789.  
  790.  
  791. const
  792.   { Define streaming mechanism for Employee Rect type }
  793.   REmpRect      : TStreamRec = (
  794.                    ObjType: st_FirstOGLType + 99;
  795.                    VmtLink: Ofs(TypeOf(TEmpRect)^);
  796.                    Load   : @TEmpRect.Load;
  797.                    Store  : @TEmpRect.Store
  798.                 );
  799.  
  800. begin
  801.   registerType(REmpRect);
  802. end.